const { createStore, applyMiddleware } = require('./redux');
const state = require('../../store/state');
const reducers = require('../../store/reducers');
const actions = require('../../store/actions');

/**
 * 这里是初始化状态值，如果底层需要处理一个初始状态值，可以在这里扩展
 * @param {object} initState - 接受对象,写法参照业务层 state
 */
const initState = {};
/**
 * 这里是初始化的 reduce，如果底层需要默认的，可以在这里扩展
 * @param {object} initReducers - 接受对象方法，写法参照业务层 reducers
 */
const initReducers = {};
/**
 * 这里是初始化的 action,如果底层需要默认，则可以在这里扩展
 * @param {object} initActions - 接受对象方法，写法参照业务层 actions
 */
const initActions = {};

/**
 * 变成动态的调用 reducer 方法
 */
function reducer(state, action) {
  const newReducers = { ...initReducers, ...reducers};
  if (typeof newReducers[action.type] === 'function') {
    const reData = reducers[action.type](state, action);
    // 把所有的状态数据存入本地 localstorage
    const key = action.type.toLowerCase();
    wx.setStorageSync(key, reData);
    return reData
  }
  return state;
}

/**
 * 这里是执行 dispatch 时中间的执行状态，如果需要对数据进行中间处理，可以在这里扩展
 */
function loggerMiddleware() {
  return next => action => {
    console.log("redux中间件", action);
    return next(action);
  };
}

/**
 * 合并业务层状态和初始状态，业务层状态值优先级更高
 */
const newState = { ...initState, ...state };

let { getState, dispatch } = createStore(
  reducer,
  newState,
  applyMiddleware(loggerMiddleware)
);

/**
 * 重写getState方法，以扩展缓存能力，值的读取方式优先级为：内存-localstorage
 * @param {object} objState -需要读取的状态值eg:['test','test2']
 * @param {object} objParam - 附加入参，这里为预留参数
 * @returns {object} - 返回指定状态数据
 */
const reGetState = function (objState = [], objParam = { }) {
  const allState = getState();
  let reState = {};
  if (typeof objState == 'object' && objState.length > 0) {
    objState.forEach(key=>{
      reState[key] =  allState[key] ? allState[key] : '';
      console.log('内存数据：', key, reState[key]);
      //如果为空，偿试去 Localstorage 获取
      if (reState[key] == '') {
        reState[key] = wx.getStorageSync(key);
        console.log("从本地获取：", key, reState[key]);
      }
    })
  } else {
    reState = allState;
  }
  return reState;
}

/**
 * 重写dispatch方法，主要是为了改变数据更改规则，变更数据优先级内存-localstorage-远程
 * 该入参对象为 action.js 的方法返回值做为入参
 * @param {function} funParam -入参 promise函数或同步函数
 * @param {string} funParam.type -  函数回调要执行的动作
 * @param {object} funParam.payload - 函数回调要修改的数据项
 * @param {number} [isCache=0] - 是否缓存到本地，1是，0不是
 * @returns {null} - 无返回
 */
const reDispatch = function (funParam, isCache = 0) {
  const { wCore } = getApp();
  if (funParam instanceof Promise) {
    funParam.then((res) => {
      console.log("dispatch 参数：", res, isCache);
      dispatch(res);
    }).catch((error) => {
      console.log("dispatch 状态失败 ", error);
    })
  } else {
    console.log("dispatch funParam的 参数：", funParam, isCache);
    dispatch(funParam);

    //要修改的属性
    const att = funParam['type'].toLowerCase();
    wCore.event.emit('watchDataAtt', att);
  }
}

/**
 * 判断某个属性是否有效, 即是否在全局状态里
 * @param {string} att - 属性名
 */
const attIsValid = function (att) {

}

/**
 * 导出外部可用的方法
 * @example
 */
module.exports = {
  getState: reGetState, 
  dispatch: reDispatch,

};

